﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Infrastructure.Utils
{
    public static class HttpHelper
    {

        /// <summary>
        /// 通用的请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<HttpResponseMessage> Request(this HttpClient http, HttpMethod httpMethod, string url, List<(string, string)> headers = null, string jsonBody = null)
        {
            //await Console.Out.WriteLineAsync(url);
            _addHeader(http, headers);
            var request = new HttpRequestMessage(httpMethod, url);
            if (jsonBody != null) request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
            return await http.SendAsync(request);
        }

        #region 普通
        /// <summary>
        /// get请求并返回字符串
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<string> GetAsync(HttpClient http, string url, string param = null, List<(string, string)> headers = null)
        {
            url = param == null ? url : $"{url}?{_serDynamicParam(param)}";
            _addHeader(http, headers);
            var res = await http.GetAsync(url);
            var responseString = await res.Content.ReadAsStringAsync();
            return responseString;
        }
        /// <summary>
        /// delete请求并返回字符串
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<string> DeleteAsync(HttpClient http, string url, string param = null, List<(string, string)> headers = null)
        {
            url = param == null ? url : $"{url}?{_serDynamicParam(param)}";
            _addHeader(http, headers);
            var res = await http.DeleteAsync(url);
            var responseString = await res.Content.ReadAsStringAsync();
            return responseString;
        }
        /// <summary>
        /// post请求并返回字符串
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<string> PostAsync(HttpClient http, string url, string data, List<(string, string)> headers = null)
        {
            var res = await http.PostAsync(url, new StringContent(data, Encoding.UTF8, "application/json"));
            _addHeader(http, headers);
            var responseString = await res.Content.ReadAsStringAsync();
            return responseString;
        }
        /// <summary>
        /// put请求并返回字符串
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<string> PutAsync(HttpClient http, string url, string data, List<(string, string)> headers = null)
        {
            var res = await http.PutAsync(url, new StringContent(data, Encoding.UTF8, "application/json"));
            _addHeader(http, headers);
            var responseString = await res.Content.ReadAsStringAsync();
            return responseString;
        }
        #endregion

        #region 另类
        /// <summary>
        /// post+query参数+body参数
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<string> PostAsync(HttpClient http, string url, string data, string param, List<(string, string)> headers = null)
        {
            url = url + "?" + _serDynamicParam(param);
            _addHeader(http, headers);
            var res = await http.PostAsync(url, new StringContent(data, Encoding.UTF8, "application/json"));
            var responseString = await res.Content.ReadAsStringAsync();
            return responseString;
        }
        /// <summary>
        /// delete +body参数
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static async Task<string> DeleteByBodyAsync(HttpClient http, string url, string data, List<(string, string)> headers = null)
        {
            var message = new HttpRequestMessage(HttpMethod.Delete, url);
            foreach (var item in headers ?? new List<(string, string)>()) message.Headers.Add(item.Item1, item.Item2);
            message.Content = new StringContent(data, Encoding.UTF8, "application/json");
            var res = await http.SendAsync(message);
            var responseString = await res.Content.ReadAsStringAsync();
            return responseString;
        }
        #endregion

        #region 组合url query参数
        /// <summary>
        /// dynamic转string 组合url query参数
        /// </summary>
        /// <param name="param">动态类型</param>
        /// <param name="rest">RestRequest</param>
        /// <param name="parent">对象参数父级名称</param>
        /// <returns></returns>
        private static string _serDynamicParam(string param, string paramStr = "", string parent = "")
        {
            var jo = JsonConvert.DeserializeObject(param) as JObject;
            if (jo == null) return "";
            foreach (var item in jo)
            {
                if (item.Value.HasValues)
                {
                    paramStr = _serDynamicParam(item.Value.ToString(), paramStr, $"{(string.IsNullOrEmpty(parent) ? "" : parent + ".")}{item.Key}");
                }
                else
                {
                    var value = item.Value.Type.ToString() == "Boolean" ? item.Value.ToString().ToLower() : item.Value.ToString();
                    paramStr = $"{(string.IsNullOrEmpty(paramStr) ? "" : paramStr + "&")}{(string.IsNullOrEmpty(parent) ? "" : parent + ".")}{item.Key}={value}";
                }
            }
            return paramStr;
        }
        #endregion

        #region 添加header
        /// <summary>
        /// 添加header
        /// </summary>
        /// <param name="param">动态类型</param>
        /// <param name="rest">RestRequest</param>
        /// <param name="parent">对象参数父级名称</param>
        /// <returns></returns>
        private static void _addHeader(HttpClient http, List<(string, string)> headers)
        {
            if (headers == null) return;
            foreach (var item in headers) http.DefaultRequestHeaders.Add(item.Item1, item.Item2);
        }
        #endregion

        /// <summary>
        /// 字符串methond转System.Net.Http.HttpMethod
        /// </summary>
        /// <param name="httpMethodString"></param>
        /// <returns></returns>
        public static HttpMethod GetHttpMethod(string httpMethodString)
        {
            httpMethodString = httpMethodString.ToLower();
            return httpMethodString switch
            {
                "get" => HttpMethod.Get,
                "post" => HttpMethod.Post,
                "put" => HttpMethod.Put,
                "delete" => HttpMethod.Delete,
                "patch" => HttpMethod.Patch,
                _ => HttpMethod.Get
            };
        }
        /// <summary>
        /// 解析键值对字符串（以换行符为分隔）
        /// </summary>
        /// <param name="Headers"></param>
        /// <returns></returns>
        public static Dictionary<string, string> ConvertToHeaderDic(string Headers)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            if (string.IsNullOrWhiteSpace(Headers)) return dic;
            string[] items = Headers.Split(new string[] { "\r\n", "\r", "\n", }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string pair in items)
            {
                var keyValue = pair.TrimStart();
                var match = Regex.Match(keyValue, "(?!^:):");// 分隔符：第一个且为非首字符的冒号 (?!^:):
                if (match.Success)
                {
                    var key = keyValue.Substring(0, match.Index).Trim();
                    var value = keyValue.Substring(match.Index + 1, keyValue.Length - (match.Index + 1)).TrimStart();
                    dic.Add(key, value);
                }
            }
            return dic;
        }
    }
}
